package com.weyoung.lxfileserver.service.impl;

import com.weyoung.common.pojo.FileInfo;
import com.weyoung.common.system.exception.BusinessException;
import com.weyoung.common.utils.FileUtils;
import com.weyoung.lxfileserver.service.LxFileService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.MultiValueMap;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 文件相关操作处理实现类
 *
 * @author Mr.wang
 * @fileName LxFileServiceImpl
 * @description
 * @date 2020/4/2 13:15
 */
@Service("lxFileService")
public class LxFileServiceImpl implements LxFileService {
    private static final Logger logger = LoggerFactory.getLogger(LxFileService.class);

    @Override
    public List<FileInfo> upload(HttpServletRequest request, String directoryPrefix) {
        List<FileInfo> fileInfoList = new ArrayList<>();
        MultipartHttpServletRequest multipartRequest = null;
        try {
            multipartRequest = (MultipartHttpServletRequest) request;
        } catch (Exception e) {
            throw new BusinessException("请求异常！", e);
        }
        MultiValueMap<String, MultipartFile> fileMap = multipartRequest.getMultiFileMap();
        List<MultipartFile> multipartFiles = new ArrayList<MultipartFile>();
        for (String key : fileMap.keySet()) {
            multipartFiles.addAll(fileMap.get(key));
        }
        if (multipartFiles.isEmpty()) {
            throw new BusinessException("没有检测到文件！");
        }
        try {
            for (MultipartFile multipartFile : multipartFiles) {
                fileInfoList.add(FileUtils.uploadFile(multipartFile, directoryPrefix));
            }
        } catch (Exception e) {
            throw new BusinessException("文件上传异常！", e);
        }
        return fileInfoList;
    }

    @Override
    public void showPicture(String filePath, boolean isThumbnail, String directoryPrefix, HttpServletResponse response) {
        String fullName = directoryPrefix + filePath;
        if (isThumbnail) {
            fullName = FileUtils.getThumbnailFilePath(fullName);
        }
        File file = new File(fullName);
        if (!file.isFile()) {
            logger.error("路径为[{}]的文件不存在！", filePath);
            throw new BusinessException("路径为[" + filePath + "]的文件不存在！");
        }
        try {
            this.outWrite(file, response);
        } catch (Exception e) {
            logger.error("路径为[{}]的图片获取失败！", filePath);
            throw new BusinessException("路径为[" + filePath + "]的图片获取失败！");
        }
    }

    @Override
    public void download(String fileFullName, String fileName, HttpServletResponse response) {
        File file = new File(fileFullName);
        if (!file.isFile()) {
            throw new BusinessException("文件不存在！");
        }
        try {
            response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, "UTF-8"));
            ServletOutputStream outputStream = response.getOutputStream();
            FileInputStream fileInputStream = new FileInputStream(fileFullName);
            byte[] b = new byte[1024];
            int len;
            while ((len = fileInputStream.read(b)) != -1) {
                outputStream.write(b, 0, len);
            }
            fileInputStream.close();
        } catch (UnsupportedEncodingException e) {
            throw new BusinessException("解码异常！", e);
        } catch (IOException e) {
            throw new BusinessException("下载异常！", e);
        }
    }

    @Override
    public void delete(Map<String, String> fileInfoMap, String directoryPrefix) {
        for (String fileName : fileInfoMap.keySet()) {
            String filePath = fileInfoMap.get(fileName);
            FileUtils.deleteFile(directoryPrefix + filePath);
            if (FileUtils.isPicture(FileUtils.getExtensionName(fileName))) {
                FileUtils.deleteFile(directoryPrefix + FileUtils.getThumbnailFilePath(filePath));
            }
        }
    }

    /**
     * 输出文件
     *
     * @param file
     * @param response
     * @throws Exception
     */
    private void outWrite(File file, HttpServletResponse response) throws Exception {
        ServletOutputStream out = response.getOutputStream();
        FileInputStream fis = new FileInputStream(file);
        FileUtils.writeStream(fis, out);
        fis.close();
        out.close();
    }
}
